<?php

namespace Tasker\Models;

use Tasker\Models\Calendar\Week,
	Tasker\Models\Calendar\Month,
	Tasker\Models\Calendar\Year,
	\Nette\DateTime;

class CalendarModel extends BaseModel
{

	public function getUserCalendar($user, $duration, $offset = 0)
	{
		return $this->getCalendar($user, $duration, $offset, 'user');
	}

	public function getProjectCalendar($project)
	{
		$start = min(new DateTime($project->task()->min('start')), new DateTime($project->milestone()->min('start')));
		$deadline = max(new DateTime($project->task()->max('start')), new DateTime($project->milestone()->max('start')), new DateTime($project['deadline']));
		$events = $this->getProjectEventsBetween($start, $deadline, $project);

		$startWeek = $start->format('W');
		$endWeek = $deadline->format('W');
		if ($endWeek > $startWeek)
			$numberOfWeeks = $endWeek - $startWeek + 1;
		else
			$numberOfWeeks = $endWeek - ( $startWeek - max(date('W', strtotime(date('Y-12-25', $startDate))), date('W', strtotime(date('Y-12-31', $startDate)))) ) + 1;

		$weeks = array();
		for ($i = 0; $i < $numberOfWeeks; $i++)
		{
			$now = $start->getTimestamp();
			$start->add(new \DateInterval('P1W'));
			if (date('N', $now) == 1)
			{
				$startDate = strtotime(date('Y-m-d 00:00:00', $now));
			} else
			{
				$startDate = strtotime("last Monday", $now);
			}
			$weeks[] = new Week($startDate, $events);
		}
		return $weeks;
	}

	protected function getCalendar($id, $duration, $offset, $type)
	{
		$now = strtotime('+' . $offset . $duration);

		if ($duration == 'week')
		{
			$end = 'next Sunday';
		} elseif ($duration == 'month')
		{
			$now = strtotime(date('Y-m-1 00:00:00', $now));
			$end = '+42days';
		} elseif ($duration == 'year')
		{
			$now = strtotime(date('Y-1-1 00:00:00', $now));
			$end = '+378days';
		}

		if (date('N', $now) == 1)
		{
			$startDate = strtotime(date('Y-m-d 00:00:00', $now));
		} else
		{
			$startDate = strtotime("last Monday", $now);
		}

		$endDate = strtotime($end, $startDate);
		if ($type == 'user')
		{
			$events = $this->getUserEventsBetween($startDate, $endDate, $id);
		} elseif ($type == 'project')
		{
			$events = $this->getProjectEventsBetween($startDate, $endDate, $id);
		}

		if ($duration == 'week')
			return new Week($startDate, $events);
		if ($duration == 'month')
			return new Month($startDate, $events);
		if ($duration == 'year')
			return new Year($startDate, $events);
	}

	protected function getUserEventsBetween($startDate, $endDate, $user)
	{
		$events = array();
		$taskList = $this->connection->task()->where('worker_id = ? OR creator_id = ?', $user, $user)->where('deadline >= ? and deadline < ?', date("Y-m-d", $startDate), date("Y-m-d", $endDate));

		foreach ($taskList as $event)
		{
			$events[strtotime($event['deadline'])]['tasks'][] = $event;
		}

		$projectList = $this->connection->project_member()->where('user_id', $user);
		$projects = array();
		foreach ($projectList as $event)
		{
			$events[strtotime($event->project['deadline'])]['projects'][] = $event->project;
			$projects[] = $event['project_id'];
		}

		$milestoneList = $this->connection->milestone()->where('project_id', $projects);
		foreach ($milestoneList as $event)
		{
			$events[strtotime($event['deadline'])]['milestones'][] = $event;
		}

		return $events;
	}

	protected function getProjectEventsBetween($startDate, $endDate, $project)
	{
		$events = array();
		if (!($startDate instanceof DateTime))
			$startDate = new DateTime($startDate);
		if (!($endDate instanceof DateTime))
			$endDate = new DateTime($endDate);

		$events[strtotime($project['deadline'])]['projects'][] = $project;

		foreach ($project->milestone() as $event)
		{
			$events[strtotime($event['start'])]['milestones']['start'][] = $event;
			$events[strtotime($event['deadline'])]['milestones']['deadline'][] = $event;
		}

		foreach ($project->task() as $event)
		{
			$events[strtotime($event['start'])]['tasks']['start'][] = $event;
			$events[strtotime($event['deadline'])]['tasks']['deadline'][] = $event;
		}

		return $events;
	}

}
